package com.greenline.push.service.core.tmpl;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.common.utils.Assert;
import com.greenline.push.core.pushcenter.GroupAppManager;
import com.greenline.push.dal.pushcenter.dataobject.GroupAppDO;
import com.greenline.push.service.core.utils.Constants;

/**
 * 
 * @Type GroupAppCache
 * @Desc GroupAppCache contains loadbyGroupId and loadByAppid
 * @author shuai.zuo
 * @date 2014年10月27日
 * @Version V1.0
 */
public class GroupAppCache {
    @Autowired
    private GroupAppManager groupAppManager;
    // 结构 appchannelId%groupid-->exegroupId
    private Map<String, String> singleGroup = new ConcurrentHashMap<String, String>();
    // 结构 appid-->extgroupIds(set)
    private Map<String, Set<String>> groups = new ConcurrentHashMap<String, Set<String>>();
    private static final String SPLITS = "%";
    private Logger log = Constants.LOG_CACHE;

    public void initial() {
        log.info("init group app cache start======");
        List<GroupAppDO> groupAppList = groupAppManager.listByAppId(null);
        Assert.notNull(groupAppList, "groupApp查询出错");

        for (GroupAppDO tmp : groupAppList) {
            String appId = tmp.getAppId();
            Long appChannelId = tmp.getAppChannelId();
            Long groupId = tmp.getGroupId();
            String singleGroupkey = appChannelId + SPLITS + groupId;
            String relativeGroupId = tmp.getRelativeGroupId();
            if (!singleGroup.containsKey(singleGroupkey)) {
                singleGroup.put(singleGroupkey, relativeGroupId);
            }

            Set<String> groupset = groups.get(appId);
            if (groupset == null) {
                groupset = new HashSet<String>();
                groupset.add(tmp.getRelativeGroupId());
                groups.put(appId, groupset);
            } else if (groupset != null && !groupset.contains(relativeGroupId)) {
                groupset.add(relativeGroupId);
            }

        }
        log.info("init group app cache end======");

    }

    public boolean reload() {
        log.info("reload group app start======");
        List<GroupAppDO> groupAppList = groupAppManager.listByAppId(null);
        Assert.notNull(groupAppList, "查询groupapp列表出错");

        // clear
        singleGroup.clear();
        groups.clear();

        // load
        try {
            for (GroupAppDO tmp : groupAppList) {
                String appId = tmp.getAppId();
                Long appChannelId = tmp.getAppChannelId();
                Long groupId = tmp.getGroupId();
                String singleGroupkey = appChannelId + SPLITS + groupId;
                String relativeGroupId = tmp.getRelativeGroupId();
                if (!singleGroup.containsKey(singleGroupkey)) {
                    singleGroup.put(singleGroupkey, relativeGroupId);
                }

                Set<String> groupset = groups.get(appId);
                if (groupset == null) {
                    groupset = new HashSet<String>();
                    groupset.add(tmp.getRelativeGroupId());
                    groups.put(appId, groupset);
                } else if (groupset != null && !groupset.contains(relativeGroupId)) {
                    groupset.add(relativeGroupId);
                }

                log.info("reload group app end======");

            }
            return true;
        } catch (Exception e) {
            log.error("reload groupo app error====" + e.getMessage());
            return false;
        }
    }

    /**
     * return ext groupids under one appid
     * 
     * @param appId
     * @return
     */
    public Set<String> loadByAppId(String appId) {
        return groups.get(appId);
    }

    /**
     * return ext groupId
     * 
     * @return
     */
    public String loadByGroupId(Long appChannelId, Long groupId) {
        return singleGroup.get(appChannelId + SPLITS + groupId);
    }

}
